#Binary parser MuOnline_BMDlate

import os, sys
from Sanae3D.lib.ModelObject import Model3D
from Sanae3D.lib.StructReader import StructReader

class MuOnline_BMD(Model3D):
    
    def __init__(self, obj3D=None, outFile=None, inFile=None):
        
        super(MuOnline_BMD,self).__init__("BMD")
        self.obj3D = obj3D
        self.inFile = inFile
        self.outFile = outFile
        self.normArray = []
        self.uvArray = []
        
    def parse_vertices(self, numVerts, meshName):
        
        for i in range(numVerts):
            unk = self.inFile.read_long()
            vx, vy, vz = self.inFile.read_float(3)
            
            vx = float(vx) * -1
            
            self.create_vertex(meshName, i)
            self.add_coords(meshName, i, [vx, vy, vz])
            
    def parse_normals(self, numNorms):

        for i in range(numNorms):
            unk1 = self.inFile.read_long()
            nx, ny, nz = self.inFile.read_float(3)
            unk2 = self.inFile.read_long()
            
            self.normArray.append([nx, ny, nz])
            
    def parse_tex_coords(self, numUV):
        
        for i in range(numUV):
            tu, tv = self.inFile.read_float(2)
            self.uvArray.append([tu, tv])
            
    def parse_materials(self):
        
        texName = self.inFile.read_string(32)
        print texName.strip("\x00")
            
    def parse_faces(self, numFaces, meshName):
        
        print "%d faces" %numFaces
        for i in range(numFaces):
            faceType, unk1 = self.inFile.read_byte(2)
            
            #vert indices
            v1, v2, v3, unk1 = self.inFile.read_short(4)
            #normal indices
            n1, n2, n3, unk2 = self.inFile.read_short(4)
            #uv indices
            uv1, uv2, uv3 = self.inFile.read_short(3)
            
            print v1, v2, v3, n1, n2, n3, uv1, uv2, uv3
            self.create_face(meshName, i)
            self.add_face_verts(meshName, i, [v1, v2, v3])
            #self.add_face_normals(meshName, i, [self.normArray[n1], \
                                    #self.normArray[n2], self.normArray[n3]])
            #self.add_face_uv(meshName, i, [self.uvArray[uv1], \
                                        #self.uvArray[uv2], self.uvArray[uv3]])
            
            #store norms and uv with faces
            self.inFile.read_byte(40)
        
    def parse_meshes(self, numMesh):
        
        print "%d meshes" %numMesh
        for i in range(numMesh):
            numVerts, numNorms, numUV, numFaces = self.inFile.read_short(4)
            meshNum = self.inFile.read_short()
            
            meshName = "Obj[%d]" %meshNum
            self.create_object(meshName)
            
            self.parse_vertices(numVerts, meshName)
            self.parse_normals(numNorms)
            self.parse_tex_coords(numUV)
            self.parse_faces(numFaces, meshName)
            self.parse_materials()
        
    def parse_file(self):
        '''Main parser method.'''
        
        magic = self.inFile.read_string(3)
        encoding = self.inFile.read_byte()
        if encoding == 0x0A:
            sourceFile = self.inFile.read_string(32)
            numMesh, unk1, unk2 = self.inFile.read_short(3)
            
            self.parse_meshes(numMesh)
        else:
            print "Unrecognized format:", encoding
        
def read_file(path):
    '''Read the file'''
    
    openFile = StructReader(open(path, 'rb'))
    obj = MuOnline_BMD(inFile=openFile)
    obj.parse_file()
    openFile.close()
    return obj

def write_file(path):
    
    pass

def definitions():
    '''Return the header, extension, and a description of the format'''
    
    return "BMD", "BMD", "Mu Online BMD (decrypted)"

if __name__ == '__main__':
    
    file1 = "Jewel15.bmd"
    obj = read_file(file1)